#include"my_add.h"
#include"my_sub.h"

int main()
{
    int a = 10;
    int b = 20;
    
    int ret = Sub(a,b);
    printf("result:%d\n",ret);
    ret = Add(a,b);
    printf("result:%d\n",ret);
    return 0;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

//如果我们不想给对方我们的源代码，我给你提供我们的.o 可重定位目标二进制文件，让你来用你的代码进行链接就行！！！
//未来我可以给对方提供.o(方法的实现), .h(都有什么方法)
//.o(方法的实现)：我们尝试这将所有的".o文件",打一个包，给对方提供一个库文件即可！(库的本质：就是.o文件的集合)
//库文件里面就包含多个.o文件 -> 这就叫库 -> 库又分为动态库和静态库！
//交付库 -> 库文件.a .so + 匹配的头文件都给别人！
//所谓的安装：本质就是拷贝。(libxxx.a->/usr/include + .h->/lib64)
//文件打包 -> tar czf [压缩包文件名.tgz] [被压缩文件名] 
//文件解包 -> tar xzf [压缩包文件名.tgz]
//如果要链接第三方库，必须要知名库名称。


///////////////////////////////////////////////////////////////////////////////////////////////////

//静态链接
//gcc -o mymath main.c -I ./mylib/include -L ./mylib/lib -l mymath
//如果不想写这么长
//1.可以把这个.a和.h文件拷贝到系统库中(即便安装好也要 -l mymath)

//形成一个可执行程序，可能不仅仅以来一个库！
//gcc默认是动态链接的(建议行为)，对于特定的一个库，究竟是动，还是静，取决与你提供的是动态库还是静态库！
//动静态库都有，选择权在gcc(只要有一个是需要动态链接的，那么这个可执行程序就是动态链接的)

///////////////////////////////////////////////////////////////////////////////////////////////////

//动态链接
//gcc -o -fPIC(与位置无关码) my_sub.o(采用就就是相对地址)
//gcc -shared -o libmymath.so my_add.o my_sub.o
//gcc -o mymath main.c -I ./mylib/include -L ./mylib/lib -l mymath  ->err! 
//gcc，当把程序编译完，和gcc已经没关系了。(动态库是在运行的时候才慢慢加载到内存的)所以程序运行起来，OS和shell也是需要知道库在哪。
//而我的库没有在系统路径下，OS无法找到！

//运行动态库
//1、拷贝.so文件到系统共享库路径下, 一般指/usr/lib
//2、更改 LD_LIBRARY_PATH
//3、ldconfig 配置/etc/ld.so.conf.d/  + ldconfig更新
//4、在当前路径下或系统路径下创建软连接(方便)

///////////////////////////////////////////////////////////////////////////////////////////////////

//动静态库的加载

//静态库：把库中的实现拷贝到我的程序里(只能映射到虚拟地址空间的代码段) -> 未来这部分代码，必须通过相对确定的地址位置来进行访问(绝对编址的方案)
//如果我程序中又很多份相同的函数，那么我就要拷贝很多分实现到我的程序，那么就会大量浪费资源

//动态库：动态库中的指定函数的地址(start:偏移量地址；那个库中的偏移量)，写入到我们的可执行程序中！
//运行时，磁盘中的库load到物理内存中通过页表映射到虚拟内存的共享区，当一映射到共享区(立马就确定了这个库的起始地址！)
//有了其实地址再加上我的函数保存的偏移量就能运行下去。
//就算我要调用很多次相同的函数，但是我的实现只有一份，节省空间。
